#!/bin/bash
#docker-registry-clear.sh

#check jq
[ -f /usr/bin/jq ] || { echo "you need to install jq !" ; exit 0 ; }

##########
#var

# Docker Registry 地址
REGISTRY_URL=${REGISTRY_URL:=https://hub.elvin.vip}

#认证信息
USERNAME=${USERNAME:=docker}
PASSWORD=${PASSWORD:=docker}
AUTH="-u $USERNAME:$PASSWORD"

#排除列表
images_exclude='base.* node ubuntu '

#镜像名称
image_name=${image_name:=""}

#镜像保留最新数量
images_limit=${images_limit:=10}

#debug为0 开启调试，不删除镜像
debug=${debug:=1}

##########
#run

if [ -z "$image_name" ];then
# 获取所有镜像的列表
curl -ks -m 5 $AUTH "$REGISTRY_URL/v2/_catalog?n=1000" |jq -r '.repositories[]' >/tmp/docker.images.txt
#删除排除列表
if [ -n "$images_exclude" ];then
    for n in $images_exclude; do
        # echo "debug 排除 $n"
        sed -i "s@^$n@@g" /tmp/docker.images.txt
    done
    #删除空行
    sed -i '/^$/d' /tmp/docker.images.txt
fi
    image_name="$(cat /tmp/docker.images.txt)"
fi

# 检查镜像列表是否为 null
if [ -z "$image_name" ]; then
    echo "no found images"
    exit 0
fi
# echo "debug image_name $image_name"

# 遍历要删除的镜像
i=0
for img in $image_name;do
    #查询tags
    if [ $(curl -ks -m 5 $AUTH "$REGISTRY_URL/v2/$img/tags/list" |grep 'null' |wc -l) -eq 0 ];then
        tags=$(curl -ks -m 5 $AUTH "$REGISTRY_URL/v2/$img/tags/list" | jq -r '.tags[]')
    else
        tags=""
    fi
    # echo "debug $img tags: $tags"
    #按时间排序,查出需要删除的tag
    if [ -n "$tags" ];then
        delete_tag=$(for tag in $tags;do
            created_time=$(curl -ks -m 5 $AUTH "$REGISTRY_URL/v2/$img/manifests/$tag" | jq -r '.history[0].v1Compatibility' | jq -r '.created')
            echo "$created_time $tag"
        done |sort -r |awk "NR > $images_limit" | awk '{print $2}')
    else
        delete_tag=""
    fi
    # echo "debug $image_name tags $delete_tag"
    if [ -n "$delete_tag" ];then
        #根据tag删除镜像
        for t in $delete_tag; do
            if [ $debug -eq 0 ];then
                let i++
                echo "debug image_delete $img:$t #$i"
            else
                #获取Digest
                Digest=$(curl -ks -m 5 $AUTH --header "Accept: application/vnd.docker.distribution.manifest.v2+json" "$REGISTRY_URL/v2/$img/manifests/$t" -I | awk '/digest|Digest/ {print $NF}' | tr -d '\r')
                if [ -n "$Digest" ];then
                    Rs=$(curl -ks -m 2 $AUTH -X DELETE $REGISTRY_URL/v2/$img/manifests/${Digest} -I |awk '/^HTTP/ {print $2}')
                    if [ "$Rs" = "202" ]; then
                        let i++
                        echo -e "\033[36m#$i $img:$t deleted\033[0m"
                    else
                        echo -e "\033[31m$img:$t delete error\033[0m"
                    fi
                fi
            fi
        done
    fi
done

if [ $i -ge 1 ];then
    echo ""
    echo "#delete $i images"
fi

#run in registry
#registry garbage-collect /etc/docker/registry/config.yml
